Source: swipeFullscreen.js

/** @import Player from 'video.js/dist/types/player' */
/** @import Plugin from 'video.js/dist/types/plugin' */
/** @import {MobileUiOptions} from './plugin' */

/**
 * Sets up swiping to enter and exit fullscreen.
 *
 * @this {Plugin}
 * @param {Player} player
 *  The player to initialise on.
 * @param {MobileUiOptions} pluginOptions
 *  The options used by the mobile ui plugin.
 */
const initSwipe = (player, pluginOptions) => {
  const {swipeToFullscreen, swipeFromFullscreen} = pluginOptions.fullscreen;

  if (swipeToFullscreen) {
    player.addClass('using-fs-swipe-up');
  }
  if (swipeFromFullscreen) {
    player.addClass('using-fs-swipe-down');
  }

  let touchStartY = 0;
  let couldBeSwiping = false;
  const swipeThreshold = 30;

  /**
   * Monitor the possible start of a swipe
   *
   * @param {TouchEvent} e Triggering touch event
   */
  const onStart = (e) => {
    const isFullscreen = player.isFullscreen();

    if (
      (!isFullscreen && !swipeToFullscreen) ||
      (isFullscreen && !swipeFromFullscreen)
    ) {
      couldBeSwiping = false;
      return;
    }

    touchStartY = e.changedTouches[0].clientY;
    couldBeSwiping = true;
    player.tech_.el().style.transition = '';
  };

  /**
   * Monitor the movement of a swipe
   *
   * @param {TouchEvent} e Triggering touch event
   */
  const onMove = (e) => {
    if (!couldBeSwiping) {
      return;
    }

    const currentY = e.touches[0].clientY;
    const deltaY = touchStartY - currentY;
    const isFullscreen = player.isFullscreen();

    let scale = 1;

    if (!isFullscreen && deltaY > 0) {
      // Swiping up to enter fullscreen: Zoom in (Max 1.1)
      scale = 1 + Math.min(0.1, deltaY / 500);
      player.tech_.el().style.transform = `scale(${scale})`;
    } else if (isFullscreen && deltaY < 0) {
      // Swiping down to exit fullscreen: Zoom out (Min 0.9)
      scale = 1 - Math.min(0.1, Math.abs(deltaY) / 500);
      player.tech_.el().style.transform = `scale(${scale})`;
    }
  };

  /**
   * Monitor the touch end to determine a valid swipe
   *
   * @param {TouchEvent} e Triggering touch event
   */
  const onEnd = (e) => {
    if (!couldBeSwiping) {
      return;
    }
    couldBeSwiping = false;

    player.tech_.el().style.transition = 'transform 0.3s ease-out';
    player.tech_.el().style.transform = 'scale(1)';

    if (e.type === 'touchcancel') {
      return;
    }

    const touchEndY = e.changedTouches[0].clientY;
    const deltaY = touchStartY - touchEndY;

    if (deltaY > swipeThreshold && !player.isFullscreen()) {
      player.requestFullscreen().catch((err) => {
        player.log.warn('Browser refused fullscreen', err);
      });
    } else if (deltaY < -swipeThreshold && player.isFullscreen()) {
      player.exitFullscreen();
    }
  };

  player.el().addEventListener('touchstart', onStart, { passive: true });
  player.el().addEventListener('touchmove', onMove, { passive: true });
  player.el().addEventListener('touchend', onEnd, { passive: true });
  player.el().addEventListener('touchcancel', onEnd, { passive: true });

  player.on('dispose', () => {
    player.el().removeEventListener('touchstart', onStart, { passive: true });
    player.el().removeEventListener('touchmove', onMove, { passive: true });
    player.el().removeEventListener('touchend', onEnd, { passive: true });
    player.el().removeEventListener('touchcancel', onEnd, { passive: true });
    player.tech_.el().style.transform = '';
    player.tech_.el().style.transition = '';
  });

};

export default initSwipe;